using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;

namespace ICSharpCode.TextEditor.Utils
{
	public static class EventHelperUtils
	{
		private static readonly Dictionary<Type, List<FieldInfo>> DicEventFieldInfos = new Dictionary<Type, List<FieldInfo>>();

		private static BindingFlags AllBindings => BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private static IEnumerable<FieldInfo> GetTypeEventFields(Type t)
		{
			if (EventHelperUtils.DicEventFieldInfos.TryGetValue(t, out var value))
			{
				return value;
			}
			List<FieldInfo> list = new List<FieldInfo>();
			EventHelperUtils.BuildEventFields(t, list);
			EventHelperUtils.DicEventFieldInfos.Add(t, list);
			return list;
		}

		private static void BuildEventFields(Type t, List<FieldInfo> lst)
		{
			EventInfo[] events = t.GetEvents(EventHelperUtils.AllBindings);
			foreach (EventInfo eventInfo in events)
			{
				Type declaringType = eventInfo.DeclaringType;
				if (declaringType != null)
				{
					FieldInfo field = declaringType.GetField(eventInfo.Name, EventHelperUtils.AllBindings);
					if (field != null)
					{
						lst.Add(field);
					}
				}
			}
		}

		private static EventHandlerList GetStaticEventHandlerList(Type t, object obj)
		{
			MethodInfo method = t.GetMethod("get_Events", EventHelperUtils.AllBindings);
			return (EventHandlerList)method.Invoke(obj, new object[0]);
		}

		public static void RemoveAllEventHandlers(object obj)
		{
			EventHelperUtils.RemoveEventHandler(obj, string.Empty);
		}

		public static void RemoveEventHandler(object obj, string eventName)
		{
			if (obj == null)
			{
				return;
			}
			Type type = obj.GetType();
			IEnumerable<FieldInfo> typeEventFields = EventHelperUtils.GetTypeEventFields(type);
			EventHandlerList eventHandlerList = null;
			foreach (FieldInfo item in typeEventFields)
			{
				if (eventName != string.Empty && string.Compare(eventName, item.Name, StringComparison.OrdinalIgnoreCase) != 0)
				{
					continue;
				}
				if (item.IsStatic)
				{
					if (eventHandlerList == null)
					{
						eventHandlerList = EventHelperUtils.GetStaticEventHandlerList(type, obj);
					}
					object value = item.GetValue(obj);
					Delegate @delegate = eventHandlerList[value];
					if ((object)@delegate != null)
					{
						Delegate[] invocationList = @delegate.GetInvocationList();
						EventInfo @event = type.GetEvent(item.Name, EventHelperUtils.AllBindings);
						Delegate[] array = invocationList;
						foreach (Delegate handler in array)
						{
							@event.RemoveEventHandler(obj, handler);
						}
					}
					continue;
				}
				EventInfo event2 = type.GetEvent(item.Name, EventHelperUtils.AllBindings);
				if (!(event2 != null))
				{
					continue;
				}
				object value2 = item.GetValue(obj);
				Delegate delegate2 = value2 as Delegate;
				if ((object)delegate2 != null)
				{
					Delegate[] invocationList2 = delegate2.GetInvocationList();
					foreach (Delegate handler2 in invocationList2)
					{
						event2.RemoveEventHandler(obj, handler2);
					}
				}
			}
		}
	}
}
